bigclown-gateway: backport pending patch to fix JSON dumps
authorJosef Schlehofer <[email protected]>
Wed, 22 Oct 2025 00:49:54 +0000 (02:49 +0200)
committerJosef Schlehofer <[email protected]>
Fri, 31 Oct 2025 11:47:46 +0000 (12:47 +0100)
Pull request:
https://redirect.github.com/hardwario/bch-gateway/pull/20

Signed-off-by: Josef Schlehofer <[email protected]>
utils/bigclown/bigclown-gateway/0002-fix-support-for-decimals.patch [new file with mode: 0644]

diff --git a/utils/bigclown/bigclown-gateway/0002-fix-support-for-decimals.patch b/utils/bigclown/bigclown-gateway/0002-fix-support-for-decimals.patch
new file mode 100644 (file)
index 0000000..1736cc9
--- /dev/null
@@ -0,0 +1,65 @@
+From df50e792cbc0c6e03fde2397e9802c81bca1c89b Mon Sep 17 00:00:00 2001
+From: Martin Pecka <[email protected]>
+Date: Wed, 22 Oct 2025 02:15:04 +0200
+Subject: [PATCH] Fix support for Decimals
+
+---
+ bcg/gateway.py | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+--- a/bcg/gateway.py
++++ b/bcg/gateway.py
+@@ -11,11 +11,26 @@ import yaml
+ import serial
+ import paho.mqtt.client
+ import appdirs
++from collections.abc import Mapping, Iterable
+ if platform.system() == 'Linux':
+     import fcntl
++# https://stackoverflow.com/a/60243503/1076564
++class DecimalJSONEncoder(json.JSONEncoder):
++    """Add support for encoding Decimal"""
++    def encode(self, obj):
++        if isinstance(obj, Mapping):
++            return '{' + ', '.join(f'{self.encode(k)}: {self.encode(v)}' for (k, v) in obj.items()) + '}'
++        if isinstance(obj, Iterable) and (not isinstance(obj, str)):
++            return '[' + ', '.join(map(self.encode, obj)) + ']'
++        if isinstance(obj, decimal.Decimal):
++            # using normalize() gets rid of trailing 0s, using ':f' prevents scientific notation
++            return f'{obj.normalize():f}'
++        return super().encode(obj)
++
++
+ class Gateway:
+     def __init__(self, config):
+@@ -218,7 +233,7 @@ class Gateway:
+             node_id = self._node_rename_name.get(node_name, None)
+             if node_id:
+                 topic = node_id + topic[i:]
+-        line = json.dumps([topic, payload], use_decimal=True) + '\n'
++        line = json.dumps([topic, payload], cls=DecimalJSONEncoder) + '\n'
+         line = line.encode('utf-8')
+         logging.debug("write %s", line)
+         self.ser.write(line)
+@@ -226,7 +241,7 @@ class Gateway:
+     def publish(self, topic, payload):
+         if isinstance(topic, list):
+             topic = '/'.join(topic)
+-        self.mqttc.publish(self._config['base_topic_prefix'] + topic, json.dumps(payload, use_decimal=True), qos=1)
++        self.mqttc.publish(self._config['base_topic_prefix'] + topic, json.dumps(payload, cls=DecimalJSONEncoder), qos=1)
+     def log_message(self, line):
+         logging.debug('log_message %s', line)
+@@ -324,7 +339,7 @@ class Gateway:
+             if node_name:
+                 subtopic = node_name + '/' + topic
+-            self.mqttc.publish(self._config['base_topic_prefix'] + "node/" + subtopic, json.dumps(payload, use_decimal=True), qos=self._msg_qos, retain=self._msg_retain)
++            self.mqttc.publish(self._config['base_topic_prefix'] + "node/" + subtopic, json.dumps(payload, cls=DecimalJSONEncoder), qos=self._msg_qos, retain=self._msg_retain)
+         except Exception:
+             raise